/*
 * PopupOSAL.cpp
 *
 *  Created on: Jul 4, 2013
 *      Author: guillou
 */
#include <stdio.h>
#include <string>
#include <errno.h>
#include <PopupOSAL.hpp>

using namespace std;
using namespace PopupUtils;

unsigned long long PopupUtils::checksum(const string & p_path)
{
#define CHECKSUM_BUFF_SIZE 1048576 // 1024*1024 = 1MB

  unsigned long long _sum = (unsigned long long) (-1);
  unsigned char _buffer[CHECKSUM_BUFF_SIZE];

  if (fexists(p_path))
  {
    ssize_t _nbcopied = 0;
    size_t _nbremaining = getFileSize(p_path);

    // Open file
    FileStream *_f = openFileStream(p_path, "r");
    if (_f != 0)
    {
      while (_nbremaining > 0)
      {
        _nbcopied = fillBufferFromStream(_buffer,
                      POPUP_MACRO_MIN(_nbremaining, CHECKSUM_BUFF_SIZE), _f);

        // Force loop exit in case read failed
        if (_nbcopied == 0)
        {
          error("Error during checksum computation for file %s",
                p_path.c_str());
          _nbremaining = 0;
          _sum = 0;
        }
        // Update checksum otherwise
        else
        {
          for (int _i = 0; _i < _nbcopied; _i++)
          {
            _sum = _sum * 37 + _buffer[_i];
          }

          // Update remaining number of bytes to read
          _nbremaining -= _nbcopied;
        }
      }
      closeFileStream(_f);
    }
  }

  return _sum;
}


